/**
 *    @file       logwrite.h
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       12/13/2012 03:43:27 PM
 *
 *    @author     Theophilus, wangtf418@gmail.com
 */
#ifndef _BF_LOGWRITE_H_
#define _BF_LOGWRITE_H_
#include <string>
#include "cfile.h"
#include "threadmutex.h"

#define LOGTYPE_LOG 0
#define LOGTYPE_RUNTIME 1
#define LOGTYPE_TRACE 2
#define LOGTYPE_DEBUG 3
#define LOGTYPE_ERROR 4

#define LOGTYPE_FILE 5
#define LOGTYPE_SOCKET 6
#define LOGTYPE_DB 7
#define LOGTYPE_MEM 8
#define LOGTYPE_SYS 9

#define MAX_LOG_FILE_SIZE 4194304
#define DEF_LOG_FILE_NUM 10

#define DEF_LOG_MODULE_NUM 20

class logmodule
{
public:
	logmodule();
	~logmodule();

public:
	bf_int_t init(bf_int_t logtype, const std::string &filename, bf_uint_t filenum, bf_bool_t openflag);
	void set_openflag(bf_bool_t openflag);
	inline bf_bool_t get_openflag() {return m_openflag;}

public:
	void writelog(const bf_char_t *format, ...);

private:
	bf_int_t m_logtype;
	std::string m_filename;
	bf_uint_t m_filenum;
	bf_int_t m_fileindex;
	volatile bf_bool_t m_openflag;
	cfile m_logfile;
	threadmutex m_lock;
	bf_size_t m_filesize;
};

#define WRITE_LOG(logtype, format, ...) if(logwrite::get_openflag(logtype)) logwrite::get_logmodule(logtype).writelog(format, ##__VA_ARGS__)
class logwrite
{
public:
	static bf_int_t init(const std::string& logdir = "logs", bf_int_t modulenum = DEF_LOG_MODULE_NUM);
	static bf_int_t add_logmodule(bf_int_t logtype, const std::string &filename, bf_uint_t filenum, bf_bool_t openflag);

public:
	static inline logmodule& get_logmodule(bf_int_t logtype)
	{
		return m_logmodule[logtype];	
	}

	static inline bf_bool_t get_openflag(bf_int_t logtype)
	{
		if (logtype < 0 || logtype >= m_modulenum)
		{
			return 0;
		}
		return m_logmodule[logtype].get_openflag();
	}

	static inline bf_int_t set_openflag(bf_int_t logtype, bf_bool_t openflag)
	{
		if (logtype < 0 || logtype >= m_modulenum)
		{
			return BF_ERROR;
		}
		m_logmodule[logtype].set_openflag(openflag);
		return BF_OK;
	}
	
protected:
	static logmodule* m_logmodule;
	static bf_int_t m_modulenum;
	static std::string m_logfiledir;
};

#endif

